/**
 * @file	FCSConveyorTest.cpp
 *
 * @brief	Will test interaction between Factory Control System Agent and Conveyor Agent
 * 			
 * @author	Anoop Kamboj
 */

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "FactoryControlSystemAgent.h"
#include "ConveyorAgent.h"
#include "KitMock.h"
#include "KitRecipe.h"
#include "Enums.h"
#include <string>
#include <iostream>

class ConveyorAgent;

std::string FCSConveyorTestString="FCS and Conveyor Test";

/**
 * @class	FCSConveyorTest
 *
 * @brief	Will test interaction between Factory Control System Agent and Conveyor Agent
 *
 * @author	Anoop Kamboj
 */

class FCSConveyorTest : public ::testing::Test
{
public:

	FCSConveyorTest()
	{
	}

	virtual void SetUp()
	{
	}
};

TEST(FCSConveyorTest, FCSandConveyor)
{
	FactoryControlSystemAgent fcs("FCS");
	ConveyorAgent conveyor("Conveyor", ConveyorType::Conveyor_In);

	fcs.setConveyor(&conveyor);
	conveyor.setFCS(&fcs);

	KitMock* kit = new KitMock();
	KitRecipe* kitRecipe = new KitRecipe();
	int numKits = 1;

	// Pick and Execute an Action should return false because there are no kits in its list of kits
	EXPECT_FALSE(fcs.pickAndExecuteAnAction());

	fcs.msgHereIsKitOrder(kitRecipe);

	// FCS should no have 1 kit in its list of kits
	EXPECT_EQ(1, fcs.getKitRecipes()->size());

	// FCS should send msgHereAreKits to conveyor once the fcs's scheduler is called
	bool result = fcs.pickAndExecuteAnAction();

	// Pick and Execute an Action should return true now that there is a KitRecipe
	EXPECT_TRUE(result);
	
	// The FCS should now have one less KitRecipe in its list
	EXPECT_EQ(numKits - 1, fcs.getKitRecipes()->size());

	// Pick and Execute an Action should return false now because it doesn't have any kit Recipes
	EXPECT_FALSE(fcs.pickAndExecuteAnAction());

	// Simulate Kit being finished and being told to send out of factory

	// Remove the kit from list
	conveyor.kitRecipes.pop_front();

	// Now list of kits should be empty
	EXPECT_EQ(0, conveyor.kitRecipes.size());

	conveyor.msgHereIsFinishedKit(kit);

	// Conveyor should now have 1 kit in its list of kits
	EXPECT_EQ(1, conveyor.finishedKits.size());

	bool conveyorResult = conveyor.pickAndExecuteAnAction();

	// Conveyor's Pick and Execute An Action should return true now because it has a good kit to send to the FCS
	EXPECT_TRUE(conveyorResult);

	// Make sure that the kit's status was set to FINISHED
	//EXPECT_EQ(fcs.FINISHED, fcs.getKits()->front()->state);

	conveyorResult = conveyor.pickAndExecuteAnAction();

	// Now conveyor's Pick And Execute and Action should return false because it has nothing to do
	EXPECT_FALSE(conveyorResult);
}